package com.bvgol.example.rabbitmq.config;

import com.alibaba.fastjson.JSONObject;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

/**
 * @program: my-spring-completely
 * @description: json序列化器
 * @author: GUOCHEN
 * @create: 2021/03/17 14:28
 */
@Configuration
public class RabbitMqConfig {

//    @Lazy
//    @Autowired
    RabbitTemplate rabbitTemplate;

    @Primary
    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        this.rabbitTemplate = rabbitTemplate;

        rabbitTemplate.setMessageConverter(messageConverter());
        rabbitTemplate.setMandatory(true);
        initRabbitTemplate();
        return rabbitTemplate;
    }

    @Bean
    //发送的对象消息用json序列化方式
    public MessageConverter messageConverter() {
        return new Jackson2JsonMessageConverter();
    }

    /**
     * 定制RabbitTemplate
     * 1、服务收到消息就会回调
     * 1、spring.rabbitmq.publisher-confirms: true
     * 2、设置确认回调
     * 2、消息正确抵达队列就会进行回调
     * 1、spring.rabbitmq.publisher-returns: true
     * spring.rabbitmq.template.mandatory: true
     * 2、设置确认回调ReturnCallback
     * <p>
     * 3、消费端确认(保证每个消息都被正确消费，此时才可以broker删除这个消息)
     */
//    @PostConstruct
// 这个不需要 在config 的时候已经new,已经存在了
    public void initRabbitTemplate() {
        /**
         *只要消息成功抵达broker ack=true
         * correlationData 当前消息的唯一关联数据(消息的唯一id)
         * ack 消息是否成功收到
         * cause 失败原因
         */
        this.rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            System.out.println("只要消息成功抵达broker::setConfirmCallback::"+correlationData + "---" + ack + "----" + cause);
        });

        //setConfirmCallback::CorrelationData [id=7b16446b-abc0-4b2b-b009-1f145dc9ba13]---true----null
        /**
         * 功能描述:消息没有投递给指定的队列,就出发这个失败回调
         Returned message callback.
         * @param message the returned message.投递失败的详细信息
         * @param replyCode the reply code. 回复的状态码
         * @param replyText the reply text. 回复的文本内容
         * @param exchange the exchange. 当时这个下次发给哪个交换机
         * @param routingKey the routing key. 用的什么路由键
         */
        this.rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {
            JSONObject jo = new JSONObject();
            jo.put("message",message);
            jo.put("replyCode",replyCode);
            jo.put("replyText",replyText);
            jo.put("exchange",exchange);
            jo.put("routingKey",routingKey);
            System.out.println("消息没有投递给指定的队列::::setReturnCallback = " + jo);
        });
        /*
        setReturnCallback = {"replyText":"NO_ROUTE",
        "replyCode":312,"exchange":"hello-java-exchange",
        "message":{"body":"eyJpZCI6bnVsbCwibWVtYmVySWQiOm51bGwsIm9yZGVyU24iOiIxMzIxMyIsImNvdXBvbklkIjpudWxsLCJjcmVhdGVUaW1lIjoxNjc5MDQ0MjI3NzMxLCJtZW1iZXJVc2VybmFtZSI6bnVsbCwidG90YWxBbW91bnQiOm51bGwsInBheUFtb3VudCI6bnVsbCwiZnJlaWdodEFtb3VudCI6bnVsbCwicHJvbW90aW9uQW1vdW50IjpudWxsLCJpbnRlZ3JhdGlvbkFtb3VudCI6bnVsbCwiY291cG9uQW1vdW50IjpudWxsLCJkaXNjb3VudEFtb3VudCI6bnVsbCwicGF5VHlwZSI6bnVsbCwic291cmNlVHlwZSI6bnVsbCwic3RhdHVzIjpudWxsLCJkZWxpdmVyeUNvbXBhbnkiOm51bGwsImRlbGl2ZXJ5U24iOm51bGwsImF1dG9Db25maXJtRGF5IjpudWxsLCJpbnRlZ3JhdGlvbiI6bnVsbCwiZ3Jvd3RoIjpudWxsLCJiaWxsVHlwZSI6bnVsbCwiYmlsbEhlYWRlciI6bnVsbCwiYmlsbENvbnRlbnQiOm51bGwsImJpbGxSZWNlaXZlclBob25lIjpudWxsLCJiaWxsUmVjZWl2ZXJFbWFpbCI6bnVsbCwicmVjZWl2ZXJOYW1lIjpudWxsLCJyZWNlaXZlclBob25lIjpudWxsLCJyZWNlaXZlclBvc3RDb2RlIjpudWxsLCJyZWNlaXZlclByb3ZpbmNlIjpudWxsLCJyZWNlaXZlckNpdHkiOm51bGwsInJlY2VpdmVyUmVnaW9uIjpudWxsLCJyZWNlaXZlckRldGFpbEFkZHJlc3MiOm51bGwsIm5vdGUiOm51bGwsImNvbmZpcm1TdGF0dXMiOm51bGwsImRlbGV0ZVN0YXR1cyI6bnVsbCwidXNlSW50ZWdyYXRpb24iOm51bGwsInBheW1lbnRUaW1lIjpudWxsLCJkZWxpdmVyeVRpbWUiOm51bGwsInJlY2VpdmVUaW1lIjpudWxsLCJjb21tZW50VGltZSI6bnVsbCwibW9kaWZ5VGltZSI6bnVsbH0=",
        "messageProperties":{"contentEncoding":"UTF-8","contentLength":0,"contentType":"application/json","deliveryTag":0,"finalRetryForMessageWithNoId":false,
        "headers":{"spring_returned_message_correlation":"692dbc5d-58ec-42fe-8434-2728e7440671","__TypeId__":"com.bvgol.example.rabbitmq.entity.OrderEntity"},
        "lastInBatch":false,"priority":0,"publishSequenceNumber":0,"receivedDeliveryMode":"PERSISTENT"}},
        "routingKey":"hello2.java2"}
setC    为啥还会有这个????onfirmCallback::CorrelationData [id=692dbc5d-58ec-42fe-8434-2728e7440671]---true----null
         */
    }

}
